/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function (s) {
  // 记录字符上次出现的位置
  const charMap = new Map();
  let maxLen = 0;
  let left = 0;

  for (let right = 0; right < s.length; right++) {
    const char = s[right];
    // 如果字符重复且上次出现位置在窗口内，更新左边界
    if (charMap.has(char) && charMap.get(char) >= left) {
      left = charMap.get(char) + 1;
    }
    // 更新字符的最新位置
    charMap.set(char, right);
    // 计算当前窗口长度并更新最大长度
    maxLen = Math.max(maxLen, right - left + 1);
  }

  return maxLen;
};